package my.myorm.tool.jdbc;

import tokyocabinet.TDB;
import tokyocabinet.TDBQRY;


import java.util.*;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2010-8-27
 * Time: 9:47:16
 * To change this template use File | Settings | File Templates.
 */
public class TDBExecutor {
    
    private static TDBExecutor instance = new TDBExecutor();
    private boolean isOpen = false;
    private Map<String, TDB> tdbMap = new HashMap<String, TDB>();

    private Log logger = LogFactory.getLog(TDBExecutor.class);


    public boolean open() throws Exception {
        if (isOpen) {
            throw new Exception("####open fail:database is allready open");
        }
        //数据库文件夹
        String tdbpath = com.mtbu.comm.PropUtil.getInstance("constant").getProperty("com.tdb.path");
        if (tdbpath == null || tdbpath.trim().equals("")) {
            tdbpath = "/home/tdb";
        }
        File database = new File(tdbpath);
        if (database == null || !database.isDirectory()) {
            logger.info("database not exist:" + tdbpath);
            return false;
        }
        File[] tables = database.listFiles();
        for (int i = 0; i < tables.length; i++) {
            //数据表文件
            if (tables[i].isFile() && tables[i].getName().endsWith(".tct")) {
                TDB tdb = new TDB();
                if (!tdb.open(tables[i].getAbsolutePath(), TDB.OWRITER | TDB.ONOLCK)) {
                    logger.info("open tdb fail:" + tables[i].getAbsolutePath());
                    return false;
                }
                tdbMap.put(tables[i].getName().substring(0,tables[i].getName().indexOf(".tct")), tdb);
            }
        }


        isOpen = true;
        return true;
    }

    public static TDBExecutor getInstance() {
        return instance;
    }

    private TDB getTdb(String tablename) {
        return tdbMap.get(tablename.toLowerCase());
    }

    public boolean set(String tablename, Map<String, Object> cols) {
        if (cols == null)
            return false;
        String[] keys = cols.keySet().toArray(new String[0]);
        for (int i = 0; i < keys.length; i++) {
            Object value = cols.get(keys[i]);
            if (value instanceof String) {
                try {
                    cols.put(keys[i], URLEncoder.encode(value + "", "utf-8"));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        String key = UUID.randomUUID().toString();
        return getTdb(tablename).put(key, cols);
    }

    public ResultList search(String tablename, List<String[]> condis) throws Exception {
        TDB tdb=getTdb(tablename);
        ResultList rl = new ResultList();
        List<byte[]> keys = searchKeys(tablename, condis);
        for (int i = 0; i < keys.size(); i++) {
            String key = new String(keys.get(i));
            Map<String, Object> o = tdb.get(key);
            if (o == null) {
                o = new HashMap<String, Object>();
            }
            String[] ks = o.keySet().toArray(new String[0]);
            for (int j = 0; j < ks.length; j++) {
                Object value = o.get(ks[j]);
                if (value instanceof String) {
                    try {
                        o.put(ks[j], URLDecoder.decode(value + "", "utf-8"));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
            DefaultBean db = new DefaultBean();
            db.setResulttype(1);
            db.setTdbdata(o);
            RecordMap rm = new RecordMap();
            rm.put(DefaultBean.class, db);
            rl.add(rm);
        }
        return rl;
    }

    public List<byte[]> searchKeys(String tablename, List<String[]> condis) throws Exception {
        TDBQRY qu = new TDBQRY(getTdb(tablename));
        for (int i = 0; i < condis.size(); i++) {
            String[] condi = condis.get(i);
            qu.addcond(condi[0], Integer.parseInt(condi[1]), condi[2]);
        }
        return qu.search();
    }

    public boolean setIndexes(String tablename, Map<String, Integer> inds) {
        String[] names = inds.keySet().toArray(new String[0]);
        for (int i = 0; i < names.length; i++) {
            String name = names[i];
            int itype = inds.get(name);
            boolean rt = getTdb(tablename).setindex(name, itype);
            if (!rt) {
                logger.info("index fail," + tablename + "[" + name + ":" + itype + "]");
                return false;
            }
        }
        return true;
    }

    public boolean close() {
        /*  if(!tdb.close()){
           return false;
       }
       isOpen=false;*/
        return false;
    }
}
